/*********************************************Copyright (c)***********************************************
** Wuhan TB
**
**--------------File Info---------------------------------------------------------------------------------
** File name:               none
** Latest modified Date:    none
** Latest Version:          none
** Descriptions:            none
**
**--------------------------------------------------------------------------------------------------------
** Created by:              Huangshihong
** Created date:            none
** Version:                 none
** Descriptions:            none
**
**--------------------------------------------------------------------------------------------------------
** Modified by:             
** Modified date:           
** Version:                 
** Descriptions:            
**
*********************************************************************************************************/
#ifndef __LOG_H
#define __LOG_H

#ifdef  __cplusplus
extern  "C" {
#endif
/********************************************************************************************************
** Includes
*********************************************************************************************************/	

	
/********************************************************************************************************
** Global variable
*********************************************************************************************************/

/********************************************************************************************************
** Defined
*********************************************************************************************************/
enum {
	LOG_ERR	= 1U << 0,
	LOG_WARNING	= 1U << 1,
	LOG_INFO	= 1U << 2,
	LOG_DEBUG	= 1U << 3,
	LOG_DEBUG1	= 1U << 4,
	LOG_DEBUG2	= 1U << 5,
	LOG_DEBUG3	= 1U << 6,
	LOG_DEBUG4	= 1U << 7,
};


#define LOG_TAG_DEFALUT_LEVEL (LOG_ERR | LOG_WARNING | LOG_INFO)

struct log_tag {
	const char *name;
	unsigned int level;
};

#define printf_notag_log(fmt,arg...)            printf(fmt,##arg)

#define printf_log(fmt,arg...)                  printf(fmt,##arg)
//#define printf_log(fmt,arg...)                  

#define TAG_STRUCT_NAME(name) _tag_##name

#define fmt_tag(TAG, LEVEL) "[" #LEVEL "/" #TAG "] "

#define LOG_REGIST()							\
	LOG_REGIST_TAG_LEVEL(LOG_TAG, LOG_TAG_DEFALUT_LEVEL)

#define LOG_REGIST_LEVEL(level)					\
	LOG_REGIST_TAG_LEVEL(LOG_TAG, level)

#define LOG_REGIST_TAG_LEVEL(name, level)				\
	_LOG_REGIST_TAG_LEVEL(name, level)

#define _LOG_REGIST_TAG_LEVEL(name, level)				\
	static struct log_tag TAG_STRUCT_NAME(name)		\
	__attribute__((unused, __section__("__log_tag")))		\
	= { #name, level }			


#define log_err(x...)          _log_err(LOG_TAG, ##x)
#define _log_err(TAG, x...)    __log_err(TAG, ##x)
#define __log_err(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_ERR)		\
			printf_log(fmt_tag(TAG, E) fmt, ##__VA_ARGS__);	\
	} while (0)

#define log_warn(x...)         _log_warn(LOG_TAG, ##x)
#define _log_warn(TAG, x...)   __log_warn(TAG, ##x)
#define __log_warn(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_WARNING)		\
			printf_log(fmt_tag(TAG, W) fmt, ##__VA_ARGS__);	\
	} while (0)

#define log_info(x...)         _log_info(LOG_TAG, ##x)
#define _log_info(TAG, x...)   __log_info(TAG, ##x)
#define __log_info(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_INFO)		\
			printf_log(fmt_tag(TAG, I) fmt, ##__VA_ARGS__);	\
	} while (0)

#define log_debug(x...)        _log_debug(LOG_TAG, ##x)
#define _log_debug(TAG, x...)  __log_debug(TAG, ##x)
#define __log_debug(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_DEBUG)		\
			printf_log(fmt_tag(TAG, D) fmt, ##__VA_ARGS__);	\
	} while (0)

#define log_debug1(x...)       _log_debug1(LOG_TAG, ##x)
#define _log_debug1(TAG, x...) __log_debug1(TAG, ##x)
#define __log_debug1(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_DEBUG1)		\
			printf_log(fmt_tag(TAG, D1) fmt, ##__VA_ARGS__);	\
	} while (0)

#define log_debug2(x...)       _log_debug2(LOG_TAG, ##x)
#define _log_debug2(TAG, x...) __log_debug2(TAG, ##x)
#define __log_debug2(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_DEBUG2)		\
			printf_log(fmt_tag(TAG, D2) fmt, ##__VA_ARGS__);	\
	} while (0)

#define log_debug3(x...)       _log_debug3(LOG_TAG, ##x)
#define _log_debug3(TAG, x...) __log_debug3(TAG, ##x)
#define __log_debug3(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_DEBUG3)		\
			printf_log(fmt_tag(TAG, D3) fmt, ##__VA_ARGS__);	\
	} while (0)

#define log_debug4(x...)       _log_debug4(LOG_TAG, ##x)
#define _log_debug4(TAG, x...) __log_debug4(TAG, ##x)
#define __log_debug4(TAG, fmt, ...)					\
	do {								\
		if (TAG_STRUCT_NAME(TAG).level & LOG_DEBUG4)		\
			printf_log(fmt_tag(TAG, D4) fmt, ##__VA_ARGS__);	\
	} while (0)

	
/********************************************************************************************************
** Function declaration
*********************************************************************************************************/


#ifdef __cplusplus
}
#endif                                                                  /*  __cplusplus                 */

#endif                                                                  /* 					           	  	    */

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

